package cn.com.dashihui.kit;

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopFieldCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import com.jfinal.kit.PropKit;

import cn.com.dashihui.api.common.ResultMap;

public class LuceneKit {
	
	/**
	 * 根据关键字查询商品信息<br/>
	 * 注：在生成索引时，将所有直营商品按每个店铺一份的方式生成了索引，所以直营商品是重复的。在搜索时要限制店铺ID
	 * @param storeid 店铺ID
	 * @param isSelf 是否查询自营商品，1：是，其他：否
	 * @param keyword 搜索关键字
	 * @param orderBy 排序方式，1：默认，2：销售价降序，3：销售价升序
	 */
	public static Map<String,Object> search(int storeid, int isSelf, String keyword, int pageNum, int pageSize, int orderBy){
		//查询指定页数
		int start = (pageNum-1)*pageSize;
		Map<String,Object> result = ResultMap.newInstance().put("pageNumber", pageNum).put("pageSize", pageSize).getAttrs();
		try {
			SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer();
			Directory index = FSDirectory.open(Paths.get(PropKit.get("constants.lucenePath")));
			IndexReader reader = DirectoryReader.open(index);
			IndexSearcher searcher = new IndexSearcher(reader);
			//根据条件判断是否增加“自营商品”查询条件
			BooleanClause.Occur[] flags = null;
			String queryStr[] = null;
			String fields[] = null;

			if(isSelf==1){
				flags = new BooleanClause.Occur[]{BooleanClause.Occur.MUST,BooleanClause.Occur.MUST,BooleanClause.Occur.MUST,BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD};
				queryStr = new String[]{String.valueOf(storeid),"1",keyword,keyword,keyword,keyword,keyword,keyword};
				fields = new String[]{"storeid","isSelf","name","shortInfo","categoryonName","categorytwName","categorythName","categoryfoName"};
			}else{
				flags = new BooleanClause.Occur[]{BooleanClause.Occur.MUST,BooleanClause.Occur.MUST,BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD};
				queryStr = new String[]{String.valueOf(storeid),keyword,keyword,keyword,keyword,keyword,keyword};
				fields = new String[]{"storeid","name","shortInfo","categoryonName","categorytwName","categorythName","categoryfoName"};
			}
			
			//根据排序条件添加排序依据
			Sort sort = null;
			if(orderBy==1){
				//综合
				sort = Sort.INDEXORDER;
			}else if(orderBy==2){
				//价格降序
				sort = new Sort(new SortField("sellPriceForSort",SortField.Type.DOUBLE,true));
			}else if(orderBy==3){
				//价格升序
				sort = new Sort(new SortField("sellPriceForSort",SortField.Type.DOUBLE,false));
			}
	
			Query query = MultiFieldQueryParser.parse(queryStr, fields, flags, analyzer);
			TopFieldCollector collector = TopFieldCollector.create(sort, 50, false, false, false);
			searcher.search(query, collector);
			//搜索结果
			ScoreDoc[] hits = collector.topDocs(start, pageSize).scoreDocs;
			//获取搜索结果数量，并计算出总页数
			int totalRow = hits.length, totalPage = totalRow!=0?((totalRow-1)/pageSize+1):0;
			//遍历结果
			List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
			if(totalRow>start){
				for (int i = 0; i < hits.length; ++i) {
					int docId = hits[i].doc;
					Document doc = searcher.doc(docId);
					list.add(ResultMap.newInstance()
							.put("ID", doc.get("id"))
							.put("NAME", doc.get("name"))
							.put("SPEC", doc.get("spec"))
							.put("SHORTINFO", doc.get("shortInfo"))
							.put("MARKETPRICE", doc.get("marketPrice"))
							.put("SELLPRICE", doc.get("sellPrice"))
							.put("THUMB", doc.get("thumb"))
							.put("ISSELF", doc.get("isSelf"))
							.getAttrs());
				}
			}
			result.put("LIST",list);
			result.put("TOTALPAGE", totalPage);
			result.put("TOTALROW", totalRow);
			reader.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
}
